package controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import javax.swing.Timer;

import DAO.MeasurementsDao;
import DAO.VideoDao;
import database.DBManager;

public class Receiver extends Thread{

	private InputStream socketIS;
	private DBManager myDb;
	private MeasurementsDao mdao;
	private ByteBuffer bb;
	private byte read;
	private boolean isRecording;
	private Timer t;
	private int delay;
	private Sender sender;

	public Receiver(DBManager myDb, InputStream socketIS, Sender sender) throws IOException, InterruptedException {
		delay = 20000;
		this.socketIS = socketIS;
		this.myDb = myDb;
		bb = ByteBuffer.allocate(2);
		bb.order(ByteOrder.LITTLE_ENDIAN);
		mdao = new MeasurementsDao(myDb);
		isRecording = false;
		this.sender = sender ;
	
		ActionListener listener = new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				stopWebcam();
				
			}
		};
		t = new Timer(delay, listener );
	}

	public void run() {
		while(true){
			try {
				if (socketIS.available() > 0) { // if there is data in socket input
												// stream ready to be read
					read = (byte) socketIS.read();
					if ((char) read == 'M') {
						System.out.println("Read ===== M");
						//isMovement(read);
					} else if ((char) read == 'T') {
						System.out.println("Read ===== T");
						handleTemperatuur(bb);
					} else if ((char) read == 'H') {
						System.out.println("Read ===== H");
						handleHumidity(bb);
					} else if ((char) read == 'L') {
						System.out.println("Read ===== L");
						handleLight();
					} else if ((char) read == 'B') {
						System.out.println("Read ===== B");
						handleLightSensor();
					} else if ((char) read == 'D') {
						System.out.println("Read ===== D");
						handleDoor();
					}else {
						System.out.println("aantal available "+ socketIS.available());
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}

	}

	private void handleLightSensor() throws IOException {
		if (socketIS.available() > 0) {
			byte short1 = (byte) socketIS.read();
			if (socketIS.available() > 0) {
				byte short2 = (byte) socketIS.read();
				bb.put(short1);
				bb.put(short2);
				int temp = (int) bb.getShort(0);
				bb.clear();
				//TODO berekening
				double lightSensor = (100* temp)/255;
//				System.out.printf("The value of the LightSensor is: %4.1f\n", lightSensor);
				//TODO
				setLight(true);
				
				
				//set in database
				mdao.createMeasurement(6, lightSensor);
			}
		}	
	}

	private void setLight(boolean on) {
		// TODO Auto-generated method stub
		try {
			if(on){
				sender.send((byte)1);
			}else{
				sender.send((byte)0);
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void handleDoor() throws IOException {
		if (socketIS.available() > 0) {
			read = (byte) socketIS.read();
			if ((int) read == 1) {
				setLight(true);
				mdao.createMeasurement(3, 1);
			} else {
				setLight(false);
				mdao.createMeasurement(3, 0);
			}
		}
	}

	private boolean isMovement(byte read) throws IOException{
		boolean movement = false;
		if (socketIS.available() > 0) {
			read = (byte) socketIS.read();
			if ((int) read == 1) {
				setLight(true);
				movement = true;
//				System.out.printf("There is movement!\n");
				mdao.createMeasurement(1, 1);
				if(!isRecording){
					startWebcam();
				}
				if(t.isRunning()){
					t.stop();
				}
				
			} else {
				setLight(false);
//				System.out.printf("Area clear\n");
				mdao.createMeasurement(1, 0);
				if(!t.isRunning() && isRecording){
					t.setDelay(delay);
					t.start();
				}
				
			}
		}
		return movement;
	}
	
	private void startWebcam() {
		isRecording = true;
		long filename = System.currentTimeMillis();
		try {
			String cmd = "cmd /c cd \""
					+ "C:\\Program Files\\VideoLAN\\VLC3"
					+ "\" & C: & vlc3 http://localhost:8080/stream.flv --demux=dump --demuxdump-file=\"C:\\Program Files\\Apache Software Foundation\\Tomcat 6.0\\webapps\\webfarm\\videos\\"
					+ filename + ".flv";
			Runtime.getRuntime().exec(cmd);
			VideoDao v = new VideoDao(myDb);
			v.addVideo(filename, "");
		} catch (IOException e) {
			System.err.println("Receiver.startWebcam");
			e.printStackTrace();
		}

	}
	
	private void stopWebcam() {
		try {
			isRecording = false;
			t.stop();
			Runtime.getRuntime()
			.exec("cmd /c taskkill /IM vlc3.exe /f");
			System.out.println("Receiver.stopWebcam() ---- is gestopt");
		} catch (IOException e) {
			System.out.println("Receiver.run() webcam stoppen");
			e.printStackTrace();
		}
	}

	private void handleTemperatuur(ByteBuffer bb) throws IOException{
		if (socketIS.available() > 0) {
			byte short1 = (byte) socketIS.read();
			if (socketIS.available() > 0) {
				byte short2 = (byte) socketIS.read();
				bb.put(short1);
				bb.put(short2);
				int temp = (int) bb.getShort(0);
				bb.clear();
				double temp2 = ((temp / 98.898) - 45.24);
				System.out.printf("The temp is: %4.1f\n", temp2);
				
				//set in database
				mdao.createMeasurement(4, temp2);
			}
		}
	}
	
	private void handleHumidity(ByteBuffer bb) throws IOException{
		if (socketIS.available() > 0) {
			byte short1 = (byte) socketIS.read();
			if (socketIS.available() > 0) {
				byte short2 = (byte) socketIS.read();
				bb.put(short1);
				bb.put(short2);
				double humidity = (double) bb.getShort(0);
				double humidityProcent = -2.0468 + 0.0367 * humidity + (-1.5955 * 0.000001) * (humidity * humidity);

				bb.clear();
				System.out.printf("The humidity is: %4.1f\n", humidity);
				System.out.println(humidityProcent);
				//set in database
				mdao.createMeasurement(5, humidityProcent);
			}
		}
	}
	
	private void handleLight() throws IOException{
		if (socketIS.available() > 0) {
			if ((int) socketIS.read() == 1){
//				System.out.println("Lamp is aan");
				mdao.createMeasurement(2, 1);
			}else{
//				System.out.println("Lamp is uit");
				mdao.createMeasurement(2, 0);
			}
		}
	}
}